﻿using CPPEI.Coolzon.Service;
using CPPEI.Coolzon.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using CPPEI.Coolzon.Data;
using CPPEI.Coolzon.Metadata.ParserV1;
using CPPEI.Coolzon.Metadata;
using System.ServiceModel;

namespace CPPEI.Coolzon.Server.ServiceImplement
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class SyncService : ISyncService
    {
        public static List<CPPEI.Coolzon.Server.ServiceImplement.SolutionPackage> Solutions { get; set; }

        /// <summary>
        /// 扫描验证方案文件，生成版本记录，同时将方案的版本记录加载到内存中
        /// </summary>
        /// <param name="solution">方案名称</param>
        public static void VerifySolutions(string solution)
        {
            string solutionDir = CPPEI.Coolzon.Runtime.Metadata.Storage.GetSolutionDirectory(solution);
            if(Solutions == null)
            {
                Solutions = new List<CPPEI.Coolzon.Server.ServiceImplement.SolutionPackage>();
            }

            Solutions.Add((CPPEI.Coolzon.Server.ServiceImplement.SolutionPackage)FileMD5Helper.GetSolutionPackage(solutionDir));
        }

        public static int PackageSize = 1024 * 1024;
        static SyncService()
        {
            try
            {
                PackageSize = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["SyncPackgeSize"]);
            }
            catch
            {
                PackageSize = 1024 * 1024;
            }
        }

        private string SolutionDir;

        /// <summary>
        /// 获取同步计划，
        /// 将客户端传过来的localVersion和服务器的方案的版本比较（SolutionRef）
        /// 如果服务器的大于本地的或者本地为null，将服务器的方案文件版本记录转换为同步计划发给客户端。
        /// </summary>
        /// <param name="solution"></param>
        /// <param name="localVersion"></param>
        /// <returns></returns>
        public SyncSchedule GetSyncSchedule(string solution, string localVersion)
        {
            SyncSchedule result = null;
            try
            {
                Logger.InfoToTag("SyncService", string.Format("方案:{0} localVersion:{1}开始同步", solution, localVersion));
                Metadata.Solution solutionObj = SolutionXmlProxy.Load(CZEnvironment.GetSolutionMetadataFilePath(solution));
                Version vLocal = new Version("0.0.0.0");
                if (!string.IsNullOrWhiteSpace(localVersion))
                {
                    vLocal = Version.Parse(localVersion);
                }
                if (solutionObj.Version > vLocal)
                {
                    Logger.InfoToTag("SyncService", "服务器方案:{0}，localVersion:{1}，serVersion:{2}开始同步", solution, vLocal.ToString(), solutionObj.Version.ToString());
                    result = new SyncSchedule();
                    result.LastestVersion = solutionObj.Version.ToString();
                    SolutionDir = CPPEI.Coolzon.Runtime.Metadata.Storage.GetSolutionDirectory(solution);
                    result.Files = GetSyncFiles(solutionObj.Name);
                    result.IsNeedSync = true;
                }
                else
                {
                    // 没有需要同步的文件
                    result = new SyncSchedule();
                    result.LastestVersion = solutionObj.Version.ToString();
                    result.IsNeedSync = false;
                }
                return result;
            }
            catch (Exception ex)
            {
                Logger.ErrorToTag("SyncService", "{0}\n{1}", ex.Message, ex.StackTrace);
            }
            return null;
        }

        public SyncResult SyncFile(string solution, string fileName, long offset)
        {
            //Logger.InfoToTag("SyncService", string.Format("开始同步方案文件{0}", fileName));
            SyncResult result = new SyncResult();

            SolutionDir = CPPEI.Coolzon.Runtime.Metadata.Storage.GetSolutionDirectory(solution);
            string filePath = string.Format("{0}\\{1}", SolutionDir, fileName);

            int packageSize = PackageSize;
            using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                try
                {
                    long totalSize = fs.Length;
                    fs.Seek(offset, SeekOrigin.Begin);

                    if (offset + packageSize < totalSize)
                    {
                        result.Data = new byte[packageSize];
                    }
                    else
                    {
                        result.Data = new byte[totalSize - offset];
                    }

                    fs.Read(result.Data, 0, result.Data.Length);

                    result.Success = true;

                    return result;
                }
                catch (Exception ex)
                {
                    result.Success = false;
                    result.Message = ex.Message;
                    Logger.ErrorToTag("SyncService", string.Format("方案文件:{0},offset:{1}下载失败", fileName, offset));
                }
            }
            return null;
        }

        private List<SyncFile> GetSyncFiles(string solutionName)
        {
            try
            {
                List<SyncFile> synvFiles = Solutions.Find(solution => string.Equals(solution.Name, solutionName)).Files;

                return synvFiles;
            }
            catch (Exception ex)
            {
                Logger.ErrorToTag("SyncService", "获取需同步文件失败,{0}\n{1}", ex.Message, ex.StackTrace);
                return null;
            }
        }
    }
}
